package com.dynabook.ems.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;

@Configuration
public class ThreadPoolConfig {
    @Bean(name = "excelThreadPool")
    public ThreadPoolExecutor excelThreadPool() {
        int corePoolSize = Runtime.getRuntime().availableProcessors(); // 核心线程数等于 CPU 核心数
        int maximumPoolSize = corePoolSize * 2; // 最大线程数为核心线程数的 2 倍
        long keepAliveTime = 60L; // 空闲线程的存活时间
        TimeUnit unit = TimeUnit.SECONDS; // 时间单位为秒
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(500); // 阻塞队列，容量为 500
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 默认线程工厂
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy(); // 拒绝策略：调用者运行
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    @Bean(name = "DataGeneratorThreadPool")
    public ThreadPoolExecutor DataGeneratorThreadPool() {
        int corePoolSize = Runtime.getRuntime().availableProcessors(); // 核心线程数等于 CPU 核心数
        int maximumPoolSize = corePoolSize * 2; // 最大线程数为核心线程数的 2 倍
        long keepAliveTime = 60L; // 空闲线程的存活时间
        TimeUnit unit = TimeUnit.SECONDS; // 时间单位为秒
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(500); // 阻塞队列，容量为 500
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 默认线程工厂
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy(); // 拒绝策略：调用者运行
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    @Bean(name = "DeviceNameThreadPool")
    public ThreadPoolExecutor DeviceNameThreadPool() {
        int corePoolSize = Runtime.getRuntime().availableProcessors(); // 核心线程数等于 CPU 核心数
        int maximumPoolSize = corePoolSize * 2; // 最大线程数为核心线程数的 2 倍
        long keepAliveTime = 60L; // 空闲线程的存活时间
        TimeUnit unit = TimeUnit.SECONDS; // 时间单位为秒
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(500); // 阻塞队列，容量为 500
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 默认线程工厂
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy(); // 拒绝策略：调用者运行
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    /**
     * 数据导出专用线程池
     * 根据服务器CPU核心数动态配置
     * 优化：针对IO密集型任务（DB查询、Redis查询），增加线程数以提高并发度
     */
    @Bean(name = "InventoryExportThreadPool")
    public ThreadPoolExecutor InventoryExportThreadPool() {
        int cpuCores = Runtime.getRuntime().availableProcessors();
        // IO密集型任务：核心线程数设置为CPU核心数的2倍
        int corePoolSize = cpuCores * 2;
        // 最大线程数设置为CPU核心数的4倍，确保高并发下有足够线程处理
        int maximumPoolSize = cpuCores * 4;
        long keepAliveTime = 120L; // 空闲线程存活时间
        TimeUnit unit = TimeUnit.SECONDS;
        // 使用较小的队列，促使创建新线程，提高并发度
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);
        
        ThreadFactory threadFactory = new ThreadFactory() {
            private final java.util.concurrent.atomic.AtomicInteger threadNumber = new java.util.concurrent.atomic.AtomicInteger(1);
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r, "Inventory-Export-" + threadNumber.getAndIncrement());
                thread.setDaemon(false);
                // 设置为普通优先级
                thread.setPriority(Thread.NORM_PRIORITY);
                return thread;
            }
        };
        
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
        
        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }
}
